#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <cstdio>
#include <vector>
#include <cassert>
using namespace std;
class ThreadDate
{
public:
    pthread_t _tid;
    char _name[64];
    int _num;
    // ThreadDate(const pthread_t& tid, char* name)
    //     :_tid(tid) ,_name(name)
    //     {}
};

void *start_routine(void *args)
{
    sleep(1);
    ThreadDate* td = static_cast<ThreadDate*>(args); // 安全的进行强制转换
    int cnt = 10;
    while (cnt)
    {
        cout << "new thread create success name: " << td->_name << " cnt:" << cnt-- << " &cnt: " << &cnt << endl;
        sleep(1);
        //exit(1); 任何一个执行流调用exit都会使整个进程退出
        // 多线程的缺陷：健壮性或鲁棒性较差，一个线程出异常，会影响其他线程。
        // 原因：信号是发给进程的，一个线程异常，所有线程都将收到信号
        //  int* p = nullptr;
        //  *p = 1;
    }
    //线程终止方式2：
    pthread_exit((void*)td->_num);  //warning: int转成void* 4字节存在8字节的空间里

    //return nullptr; //线程终止方式1：通过返回终止

}


int main()
{
    // 操作系统提供的轻量级进程接口 clone vfork  （了解）

#define NUM 10;
    vector<ThreadDate*> threads; 
    for (int i = 0; i < 10; ++i)
    {
        ThreadDate* td = new ThreadDate;
        td->_num = i + 1;
        sprintf(td->_name, "%s:%d", "thread", i + 1);
        pthread_create(&td->_tid, nullptr, start_routine, td);
        threads.push_back(td);
        //sleep(1);
    }
    for(const auto& e : threads)
    {
        cout << "create new thread name: " << e->_name << " tid: " << e->_tid <<  "success" << endl;
    }

    //线程是可以被取消的！注意：线程要被取消，前提是这个线程已经跑起来了
    //而且线程如果被取消，默认的退出结果为-1  PTHREAD_CANCELED
    sleep(5);
    //取消5个进程
    for(int i = 0; i < 5; ++i)
    {
        pthread_cancel(threads[i]->_tid);
    }
    
    //线程也是要被等待的！如果不等待，会造成类似僵尸进程的问题 --- 内存泄漏
    //线程必须要被等待：
    //1.获取新线程的退出信息
    //2.回收新线程对应的pcb等内核资源，防止内存泄漏 -- 暂时无法查看
    for(const auto& e : threads)
    {
        void* exit_status;
        int n = pthread_join(e->_tid, &exit_status);
        assert(0 == n);
        cout << "exit_status:" << (long long)exit_status << endl;
        delete e;
    }

    cout << "main thread exit " << endl;
    // while (1)
    // {
    //     cout << "new thread create success name: main thread" << endl;
    //     sleep(1);
    // }
    
    return 0;
}